#pragma once
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iostream>
#include <string>
#include <memory>
#pragma comment(lib, "ws2_32.lib")

using namespace std;

// 连接状态枚举
enum class ClientConnectionState {
    DISCONNECTED,
    CONNECTED,
    AUTHENTICATED
};

// 前向声明
class NetworkManager;
class AuthenticationHandler;
class CommandProcessor;
class MessageTransporter;

/**
 * 网络连接管理器
 * 负责网络连接的建立、维护和关闭
 */
class NetworkManager {
public:
    NetworkManager();
    ~NetworkManager();

    bool initialize();
    bool connectToServer(const string& serverAddress, int port);
    void disconnect();
    bool isConnected() const;
    SOCKET getSocket() const;

private:
    bool initWinsock();
    void cleanupWinsock();

private:
    SOCKET clientSocket;
    bool isInitialized;
    bool connected;
};

/**
 * 消息传输管理器
 * 负责网络消息的发送和接收
 */
class MessageTransporter {
public:
    MessageTransporter(SOCKET socket);

    bool sendMessage(const string& message);
    string receiveMessage();
    bool isConnectionAlive();

private:
    SOCKET socket;
    static const int BUFFER_SIZE = 1024;
};

/**
 * 身份验证处理器
 * 负责用户身份验证流程
 */
class AuthenticationHandler {
public:
    AuthenticationHandler(shared_ptr<MessageTransporter> transporter);

    bool performAuthentication();
    string getAuthenticatedUsername() const;

private:
    bool requestCredentials(string& username, string& password);
    bool validateCredentials(const string& username, const string& password);

private:
    shared_ptr<MessageTransporter> messageTransporter;
    string authenticatedUsername;
};

/**
 * 命令处理器
 * 负责SQL命令的输入、发送和结果处理
 */
class CommandProcessor {
public:
    CommandProcessor(shared_ptr<MessageTransporter> transporter);

    void startCommandLoop();
    void executeScript(const string& scriptFile);
    bool processCommand(const string& command);
    bool confirmScriptExecution(const string& scriptFile);

private:
    string getUserInput();
    void displayResult(const string& result);
    bool isExitCommand(const string& command);

private:
    shared_ptr<MessageTransporter> messageTransporter;
};

/**
 * 数据库客户端
 * 主要的客户端控制器，协调各组件
 */
class DatabaseClient {
public:
    DatabaseClient();
    ~DatabaseClient();

    bool initialize();
    bool connectToServer(const string& serverAddress = "127.0.0.1", int port = 8080);
    void startSession();
    void startScriptSession(const string& scriptFile);
    void disconnect();

private:
    void cleanup();

private:
    unique_ptr<NetworkManager> networkManager;
    shared_ptr<MessageTransporter> messageTransporter;
    unique_ptr<AuthenticationHandler> authHandler;
    unique_ptr<CommandProcessor> commandProcessor;
    ClientConnectionState connectionState;
};